#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

typedef struct {
	char name[5];
	float sc;
} student;
typedef struct link {
	struct link *prev;
	struct link *next;
	student stu;
} link;
typedef struct list {
	link *head;
	link *tail;
	int length;

} list;
link *createlink(char *name, float sc) {
	link *p = (link *)malloc(sizeof(link));
	p->next = NULL;
	p->prev = NULL;
	strcpy(p->stu.name, name);
	p->stu.sc = sc;
	return p;
}
list *createlist() {
	list *p = (list *)malloc(sizeof(list));
	p->head = NULL;
	p->tail = NULL;
	p->length = 0;
	return p;
}
//尾插
void signup(list *l, link *node) {
	if (l->length == 0) //没有登记,此时为首次登记
		l->head = node;//将第一个设定为head
	else {
		l->tail->next = node;
		node->prev = l->tail;
	}
	l->tail = node;
	l->length++;
}
//删除指定信息
void delnode(list *l, char *name) {
	if (l->length == 0) {
		printf("未登记任何信息\n");
		return ;
	}
	link *todelete = l->head;
	while (todelete != NULL) {
		if (!strcmp(todelete->stu.name, name)) {
			if (todelete->prev) todelete->prev->next = todelete->next;
			else l->head = todelete->next; //删除头节点的情况
			if (todelete->next) todelete->next->prev = todelete->prev;
			else l->tail = todelete->prev; //删除尾节点的情况
			free(todelete);
			l->length--;
			printf("删除成功\n");
			return;
		}
		todelete = todelete->next;
	}
	printf("找不到目标\n");
}
//删除最近登记（实质为尾删）
void delrecent(list *l) {
	if (l->length == 0) {
		printf("未登记任何信息\n");
		return ;
	}  else {
		link *todelete = l->tail;
		if (l->length == 1) {
			l->head = NULL;
			l->tail = NULL;
		} else {
			l->tail = todelete->prev;
			l->tail->next = NULL;
		}
		free(todelete);
		l->length--;
		printf("删除成功\n");
	}
}
//全部删除
void delall(list *l) {
	link *node = l->head;
	if (l->length == 0) {
		printf("列表已为空\n");
		return ;
	}
	if (l->length > 1)
		while (l->length != 1) {
			node = node->next;
			free(node->prev);
			l->length--;
		}
	free(node);
	l->length = 0;
	printf("已全部删除\n");
}
//从前往后遍历
void traverse(list *l) {
	int i;
	link *node = l->head;
	for (i = 0; i < l->length; i++) {
		printf("name: %s ; score: %f\n", node->stu.name, node->stu.sc);
		node = node->next;
	}
}
//修改
void change(list *l, char *name) {
	if (l->length == 0) {
		printf("未登记任何信息\n");
		return ;
	}
	link *node = l->head;
	while (node != NULL) {
		if (!strcmp(node->stu.name, name)) {
			printf("请输入修改后的姓名 成绩: ");
			scanf("%s %f", node->stu.name, &node->stu.sc);
			printf("修改成功\n");
			return;
		}
		node = node->next;
	}
	printf("未找到目标\n");
}
void search(list *l, char *name) {
	int i;
	link *node = l->head;
	for (i = 0; i < l->length; i++) {
		if (!strcmp(node->stu.name, name)) {
			printf("目标 name：%s ; score：%f\n", node->stu.name, node->stu.sc);
			return ;
		} else node = node->next;
	}
	printf("未找到目标\n");
}

int main() {
	int fun;
	char name[5];
	float sc;
	list *p = createlist();
	while (1) {
		printf("功能列表\n1.登记学生信息 2.删除学生信息 3.修改学生信息 4.查询学生信息: \n");
		scanf("%d", &fun);
		switch (fun) {
			case 1:
resignup:
				printf("请输入登记的学生姓名 成绩: \n");
				scanf("%s %f", name, &sc);
				signup(p, createlink(name, sc));
				printf("登记成功\n");
				printf("是否需要继续登记：1.是 0.否 : ");
				scanf("%d", &fun);
				if (fun == 1)
					goto resignup;
				break;
			case 2:
				printf("当前存储的登记信息如下：\n");
				traverse(p);
				printf("请选择删除方式：1.全部删除 2.删除新增(最近登记) 3.指定删除：");
				scanf("%d", &fun);
				switch (fun) {
					case 1:
						printf("是否要全部清空，该操作不可撤回:1.是 0.否 : ");
						scanf("%d", &fun);
						if (fun == 1)
							delall(p);
						break;
					case 2:
						delrecent(p);
						break;
					case 3:
						printf("请输入删除的目标名字: ");
						scanf("%s", name);
						delnode(p, name);
						break;
				}
				break;
			case 3:
				if (p->length == 0) {
					printf("未登记任何信息\n");
					break;
				}
				printf("请输入修改的目标: ");
				scanf("%s", name);
				change(p, name);
				break;
			case 4:
				if (p->length == 0) {
					printf("未登记任何信息\n");
					break;
				}
				printf("当前登记信息如下:\n");
				traverse(p);
				printf("请输入查询目标名字: ");
				scanf("%s", name);
				search(p, name);
				break;
		}
		fun = 0;
		printf("\n\n按任意键继续");
		getch();
		system("cls");
	}
	return 0;
}
